using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using ArtificialIntelligence;
using Roslyn.Compilers;
using Roslyn.Compilers.CSharp;
namespace SymbolicComputation.AI
{
    public class SolveEquationBase
    {
        public Dictionary<SyntaxKind, List<Transform>> transforms = TransformSets.ArrangeTransformsBySyntaxKindOfRoot(TransformSets.AllAsTransforms().ToArray());
        public ArtificialIntelligence.AI ai=new ArtificialIntelligence.AI();

        public List<Transform> Transforms
        {
            set
            {
                transforms = TransformSets.ArrangeTransformsBySyntaxKindOfRoot(value.ToArray());
            }
        }

        public String Solve(String transformMe)
        {
            SyntaxNode result = Solve(Miscellaneous.EquationToSyntaxNode(transformMe));
            return result.ToString();
        }

        public SyntaxNode Solve(SyntaxNode transformMe)
        {
            Ability ability = new Ability();
            ability.WorkFunction = AbilityWorkFunction;
            ai.abilities.Add(ability);
            Distinction distinction = new Distinction();
            ai.Distinct = distinction.DistinctWorkFunction;
            Job jobSpecification = new Job();
            jobSpecification.jobState = transformMe;
            ai.Work(jobSpecification,AssessJob);
            return ai.BestJobState.jobState;
        }

        public List<Job> AbilityWorkFunction(Job inJob)
        {
            SyntaxNode jobState = inJob.jobState;
            List<HistoricalMoment> historicalMoments = new List<HistoricalMoment>();
            List<SyntaxNode> results = TransformBranchFunctions.TransformBranchesWithTransforms(jobState, transforms,ref historicalMoments);
            List<Job> lOut = Functional.Maps.Map(results, x => new Job(x));
            Functional.Maps.MapTwoArrays(historicalMoments, lOut, (x, y) => y.recentHistory = x);
            return lOut;
        }

        public virtual void AssessJob(Job passJob)
        {
            SyntaxNode equation = passJob.jobState;
            Double assessment = 0;
            assessment -= equation.ToString().Length;
            passJob.assessment = assessment;
        }
    }
}